﻿/*
 * @Autor: PK
 * @Date: 2021/12/26 10:20:SS
 */

using System.Collections;
using System.Collections.Generic;
using System.Linq;
using O2DESNet;
using ShkSimulation.core.dao.statistic.feature;
using ShkSimulation.core.exceptions;

namespace ShkSimulation.core.dao.statistic {

	public class CollectionReportData : IEnumerable<KeyValuePair<VariableAndHourStatisticKey, StatisticInfo>> {
		
		public StatisticInfo this[VariableAndHourStatisticKey variableAndHourStatisticKey] {
			get { return StatisticData[variableAndHourStatisticKey]; }
		}
		
		public StatisticInfo this[string variableName, string hourStatisticName = null] {
			get { return StatisticData[new VariableAndHourStatisticKey(variableName, hourStatisticName)]; }
		}

		public Dictionary<VariableAndHourStatisticKey, StatisticInfo> StatisticData { get; set; }

		public string ReporterCollectionUniqueKey { get; private set; }
		
		public static CollectionReportData Create(string reportersUniquekey, Dictionary<VariableAndHourStatisticKey, StatisticInfo> cloneData) {
			CollectionReportData data = new CollectionReportData();
			data.StatisticData = new Dictionary<VariableAndHourStatisticKey, StatisticInfo>(cloneData);
			data.ReporterCollectionUniqueKey = reportersUniquekey;
			return data;
		}
		
		public static CollectionReportData CreateByStatistics(string reportersUniquekey, List<StatisticInfo> statistic) {
			CollectionReportData data = new CollectionReportData();
			data.StatisticData = statistic.ToDictionary(each => each.UniqueKey);
			data.ReporterCollectionUniqueKey = reportersUniquekey;
			return data;
		}

		public static CollectionReportData Empty() {
			return new CollectionReportData();
		}
		
		public StatisticInfo GetStatisticInfo(string variableName, string hourStatistic = null) {
			return GetStatisticInfo(new VariableAndHourStatisticKey(variableName, hourStatistic));
		}

		public StatisticInfo GetStatisticInfo(VariableAndHourStatisticKey key) {
			if (StatisticData != null && StatisticData.ContainsKey(key)) {
				return StatisticData[key];
			}
			throw new ErrorParamException($"参数未找到{key}");
		}

		public bool ContainsStatisticInfo(string variableName, string hourStatisticName = null) {
			return StatisticData.ContainsKey(new VariableAndHourStatisticKey(variableName, hourStatisticName));
		}

		public IEnumerator<KeyValuePair<VariableAndHourStatisticKey, StatisticInfo>> GetEnumerator() {
			return StatisticData.GetEnumerator();
		}

		IEnumerator IEnumerable.GetEnumerator() {
			return GetEnumerator();
		}

		public static CollectionReportData ExportCollectionAction(DataReporterCollection reporters) {
			if (reporters == null || reporters.Count == 0) {
				return CollectionReportData.Empty();
			}
			List<string/*VariableName*/> doubleKeys = reporters.Template.DoubleUniqueKeys;
			List<string/*VariableName*/> hourCounterKeys = reporters.Template.HourCounterUniqueKeys;
			Dictionary<string, DataReportInfo> reportInfos = reporters.GetAllReportInfos();

			List<StatisticInfo> result = new List<StatisticInfo>();
			foreach (var variableName in doubleKeys) {
				Dictionary<string/*DataReporterKey*/, double> doubleData = new Dictionary<string, double>();
				foreach (var (key, dataReportInfo) in reportInfos) {
					doubleData.Add(key, dataReportInfo.GetDoubleValue(variableName));
				}
				StatisticInfo statistics = StatisticOptionProvider.StatisticSingleData(doubleData, variableName);
				result.Add(statistics);
			}
			foreach (var hourCounterKey in hourCounterKeys) {
				Dictionary<string/*DataReporterKey*/, ReadOnlyHourCounter> hourCounters = new Dictionary<string, ReadOnlyHourCounter>();
				foreach (var (key, dataReportInfo) in reportInfos) {
					hourCounters.Add(key, dataReportInfo.GetHourCounter(hourCounterKey));
				}
				List<StatisticInfo> statistics = StatisticOptionProvider.StatisticHourCounter(hourCounterKey, hourCounters);
				result.AddRange(statistics);
			}
			return CollectionReportData.CreateByStatistics(reporters.Uniquekey, result);
		}
		
	}

}